//
//  RPCService.swift
//  Center_RPC
//
//  Created by 蒋晨成 on 2021/12/28.
//

import Foundation
import GRPC
import Logging
import LogMan
import NIO
import Standard

open class RPCService {
    private let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)

    private let keepAlive = ClientConnectionKeepalive(interval: .seconds(60), timeout: .seconds(30))

    private let name: String

    private(set) var connection: ClientConnection

//    private(set) var channel: GRPCChannel

    private(set) lazy var logger: Logger = {
        var logger = Loggers["\(typeName).\(name)"]
        logger.logLevel = .debug
        return logger
    }()

    public init(name: String, host: String, port: Int, tls: Bool) {
        precondition(!name.isEmpty, "name should not be empty")
        self.name = name
        connection = tls.map(
            true: ClientConnection.usingTLSBackedByNIOSSL(on: group)
                .withKeepalive(keepAlive)
                .connect(host: host, port: port),
            false: ClientConnection.insecure(group: group)
                .withKeepalive(keepAlive)
                .connect(host: host, port: port)
        )
    }

    deinit {
        group.shutdownGracefully { [weak self] error in
            guard let self = self else { return }
            guard let error = error else { return }
            self.logger.error("\(error)")
        }
    }
}

extension RPCService {
    var eventLoop: EventLoop {
        group.next()
    }
}

extension RPCService {
    func change(host: String, port: Int, tls: Bool) {
        do {
            try connection.close().wait()
        } catch {
            logger.error("\(error)")
        }
        connection = tls.map(
            true: ClientConnection.usingTLSBackedByNIOSSL(on: group)
                .connect(host: host, port: port),
            false: ClientConnection.insecure(group: group)
                .connect(host: host, port: port)
        )
    }
}

extension RPCService: TypeName {}
